﻿using System;

namespace DotNetClient
{
    /*
     * 0     1     2     3     4     5
     * +-----+-----+-----+-----+-----+
     * |        length         | type|
     * +-----------+-----+-----+-----+
     * |   route   |  id |           |
     * +-----------+-----+           +
     * |         ... body ...        |
     * +-----------------------------+
     * 
     * Header
     * length: 消息长度(type + (route + id + body))
     * type: 消息类型 msg=1 handshake=2 heartbeat=3
     * 
     * Message
     * route: 路由索引
     * id: 请求唯一ID
     * body: 参数 prototbuf编码
     */

    public class PackageProtocol
    {
        private const int HEADER_LENGTH = 5;

        /// <summary>
        /// 系统消息，握手/心跳
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static byte[] encode(PackageType type)
        {
            byte[] bytes = new byte[5];
            bytes[0] = 1 >> 24 & 0xFF;
            bytes[1] = 1 >> 16 & 0xFF;
            bytes[2] = 1 >> 8 & 0xFF;
            bytes[3] = 1 & 0xFF;
            bytes[4] = Convert.ToByte(type);

            return bytes;
        }

        public static byte[] encode(PackageType type, byte[] message)
        {
            int msgLength = message == null ? 0 : message.Length;
            byte[] bytes = new byte[msgLength + HEADER_LENGTH];
            int length = msgLength + 1;

            int index = 0;
            bytes[index++] = Convert.ToByte(length >> 24 & 0xFF);
            bytes[index++] = Convert.ToByte(length >> 16 & 0xFF);
            bytes[index++] = Convert.ToByte(length >> 8 & 0xFF);
            bytes[index++] = Convert.ToByte(length & 0xFF);
            bytes[index++] = Convert.ToByte(type);

            while (index < msgLength + HEADER_LENGTH)
            {
                bytes[index] = message[index - HEADER_LENGTH];
                index++;
            }

            return bytes;
        }

        public static Package decode(byte[] bytes)
        {
            PackageType type = (PackageType)bytes[4];
            byte[] body = new byte[bytes.Length - HEADER_LENGTH];

            for (int i = 0; i < body.Length; i++)
            {
                body[i] = bytes[i + HEADER_LENGTH];
            }

            return new Package(type, body);
        }
    }
}
